home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / pctchnqs / 1992 / number2 / pardonme / pardonme.cpp < prev    next >
C/C++ Source or Header  |  1992-04-03  |  8KB  |  257 lines

  1. // pardonme.cpp -- Windows alarm program by Tom Swan
  2.  
  3. // Notes and suggestions
  4. // - hours must be in 24-hour format
  5. // - alarm times must be unique
  6. // - sort alarm times from low to high
  7. // - store alarms in a file so they can be edited
  8. // - abort program if no alarms are set
  9. // - display running time in dialog
  10. // - display list of alarms
  11.  
  12. #include <owl.h>   // ObjectWindows header
  13. #include <time.h>  // Standard library header
  14. #include "ids.h"   // Resource IDs header
  15.  
  16. #define APP_NAME "PardonMe"  // Application name
  17. #define TIMER_ID 1           // Timer identifier
  18. #define TIMER_DELAY 30000    // Half minute intervals
  19. #define EM_RUNNING -100      // Program-already-running error code
  20. #define EM_OUTOFTIMERS -101  // Out-of-timers error code
  21. #define DEFAULTMSG "No alarms set"  // Default dialog message
  22. #define NUMALARMS 5          // Number of alarms
  23.  
  24. struct Alarm {    // Alarm structure
  25.   int alarmTime;         // Alarm time in minutes
  26.   int alarmSet;          // True (nonzero) if alarm is set
  27.   const char *alarmMsg;  // Pointer to dialog message
  28. };
  29.  
  30. Alarm alarms[NUMALARMS];  // Global array of alarm structures
  31.  
  32. // The application class
  33. class TPardonApp: public TApplication
  34. {
  35. public:
  36.   TPardonApp(LPSTR aName, HANDLE hInstance, HANDLE hPrevInstance,
  37.     LPSTR lpCmd, int nCmdShow): TApplication(aName, hInstance,
  38.     hPrevInstance, lpCmd, nCmdShow) { };
  39.   void Error(int ErrorCode);
  40.   void InitInstance();
  41.   virtual void InitMainWindow();
  42. };
  43.  
  44. // The main window (as a modeless dialog!)
  45. class TPardonDlg: public TDialog
  46. {
  47. protected:
  48.   int timerSet;  // True (nonzero) if timer is set
  49.   int theDay;    // Current day (full date not needed)
  50.   int theTime;   // Current time in minutes
  51.   const char *theMsg;  // Pointer to alarm message
  52. public:
  53.   TPardonDlg(PTWindowsObject AParent, int ResourceId)
  54.     : TDialog(AParent, ResourceId) { }
  55. // Inherited member functions
  56.   virtual BOOL CanClose();
  57.   virtual LPSTR GetClassName();
  58.   virtual void GetWindowClass(WNDCLASS &AWndClass);
  59.   void SetupWindow();
  60. // New member functions
  61.   void AssignAlarm(int n, int hour, int minute, const char *msg);
  62.   void GetDayTime(int &d, int &t);
  63.   void SetAlarms(void);
  64. // Message response member functions
  65.   virtual void IDAbout(RTMessage)
  66.     = [ID_FIRST + ID_ABOUT];
  67.   virtual void IDClose(RTMessage)
  68.     = [ID_FIRST + ID_CLOSE];
  69.   virtual void IDHide(RTMessage)
  70.     = [ID_FIRST + ID_HIDE];
  71.   virtual void WMDestroy(RTMessage)
  72.     = [WM_FIRST + WM_DESTROY];
  73.   virtual void WMSysCommand(RTMessage)
  74.     = [WM_FIRST + WM_SYSCOMMAND];
  75.   virtual void WMTimeChange(RTMessage)
  76.     = [WM_FIRST + WM_TIMECHANGE];
  77.   virtual void WMTimer(RTMessage)
  78.     = [WM_FIRST + WM_TIMER];
  79. };
  80.  
  81. // Display error message. "Falls through" to end program.
  82. void TPardonApp::Error(int ErrorCode)
  83. {
  84.   LPSTR msg;            // Long pointer to string
  85.   char string[40];      // Buffer for wsprintf()
  86.   switch (ErrorCode) {
  87.     case EM_OUTOFTIMERS:
  88.       msg = "Out of timers";
  89.       break;
  90.     case EM_RUNNING:
  91.       msg = "This program is already running";
  92.       break;
  93.     default:
  94.       msg = "Window creation error";
  95.   }
  96.   wsprintf(string, "Error %d: %s", ErrorCode, msg);
  97.   MessageBox(NULL, string, APP_NAME, MB_ICONSTOP | MB_OK);
  98. }
  99.  
  100. // Initialize program instance (only one allowed)
  101. void TPardonApp::InitInstance()
  102. {
  103.   if (hPrevInstance)
  104.     Status = EM_RUNNING;  // Error: program already running
  105.   else
  106.     TApplication::InitInstance();
  107. }
  108.  
  109. // Initialize the application's main window
  110. void TPardonApp::InitMainWindow()
  111. {
  112.   MainWindow = new TPardonDlg(NULL, ID_DIALOG);
  113.   nCmdShow = SW_SHOWMINNOACTIVE;
  114. }
  115.  
  116. // Return true if okay to close dialog
  117. BOOL TPardonDlg::CanClose()
  118. {
  119.   return (MessageBox(HWindow, "End program now?",
  120.     APP_NAME, MB_YESNO) == IDYES);
  121. }
  122.  
  123. // Return window class name
  124. LPSTR TPardonDlg::GetClassName()
  125. {
  126.   return "TPardonDlg";  // Same as dialog resource class name!
  127. }
  128.  
  129. // Return window class to be registered with Windows
  130. void TPardonDlg::GetWindowClass(WNDCLASS &AWndClass)
  131. {
  132.   TDialog::GetWindowClass(AWndClass);
  133.   AWndClass.hIcon = LoadIcon(GetApplication()->hInstance,
  134.     MAKEINTRESOURCE(ID_ICON));
  135. }
  136.  
  137. // Initialize window and set the timer
  138. void TPardonDlg::SetupWindow()
  139. {
  140.   TDialog::SetupWindow();
  141.   GetDayTime(theDay, theTime);
  142.   theMsg = DEFAULTMSG;
  143.   SetAlarms();
  144. // - Set a timer to begin generating WM_TIMER messages
  145.   timerSet = SetTimer(HWindow, TIMER_ID, TIMER_DELAY, NULL);
  146.   if (!timerSet)
  147.     Status = EM_OUTOFTIMERS;  // End program if timer not set
  148. }
  149.  
  150. // Get current day number and time in minutes
  151. void TPardonDlg::GetDayTime(int &d, int &t)
  152. {
  153.   time_t secs;
  154.   struct tm *tmp;
  155.   time(&secs);  // Get time in seconds from 1/1/1970
  156.   tmp = localtime(&secs);  // Convert time to struct
  157.   d = tmp->tm_mday;  // Set d to the day number
  158.   t = tmp->tm_hour * 60 + tmp->tm_min;  // Calculate minutes
  159. }
  160.  
  161. // Assign hour, minute, and msg to alarm number n
  162. // Sets alarm to ON if time is >= current time
  163. void TPardonDlg::AssignAlarm(int n, int hour, int minute,
  164.   const char *msg)
  165. {
  166.   if (n < 0 || n >= NUMALARMS)
  167.     return;  // Ignore index n range errors
  168.   int t = hour * 60 + minute;  // Calculate time in minutes
  169.   alarms[n].alarmTime = t;
  170.   alarms[n].alarmSet = (t >= theTime);
  171.   alarms[n].alarmMsg = msg;
  172. }
  173.  
  174. // Set or reset all alarms (hours in 24-hour format)
  175. void TPardonDlg::SetAlarms(void)
  176. {
  177. //            n  hr  mn  message
  178.   AssignAlarm(0,  9, 00, "Good morning! Have a great day!");
  179.   AssignAlarm(1, 11, 50, "Lunch time in 10 minutes. Hungry?");
  180.   AssignAlarm(2, 15, 30, "Take a break. You deserve it!");
  181.   AssignAlarm(3, 17, 15, "Backup your files.");
  182.   AssignAlarm(4, 18, 10, "Are you still working? Get a life!");
  183. }
  184.  
  185. // Display about-box dialog
  186. void TPardonDlg::IDAbout(RTMessage)
  187. {
  188.   TDialog *dp = new TDialog(this, ID_ABOUTDLG);
  189.   GetApplication()->ExecDialog(dp);
  190. }
  191.  
  192. // Respond to selection of dialog's Close button
  193. void TPardonDlg::IDClose(RTMessage)
  194. {
  195.   CloseWindow();
  196. }
  197.  
  198. // Respond to selection of dialog's Hide button
  199. void TPardonDlg::IDHide(RTMessage)
  200. {
  201.   Show(SW_MINIMIZE);  // Shrink window back to a pumpkin
  202. }
  203.  
  204. // Respond to WMDestroy message. Kill timer
  205. void TPardonDlg::WMDestroy(RTMessage msg)
  206. {
  207.   TDialog::WMDestroy(msg);
  208.   if (timerSet)
  209.     KillTimer(HWindow, TIMER_ID);
  210. }
  211.  
  212. // Trap system-menu Close command
  213. void TPardonDlg::WMSysCommand(RTMessage msg)
  214. {
  215.   if (msg.WParam == SC_CLOSE) // This step required to enable
  216.     CloseWindow();            //  CanClose() function!
  217.   else
  218.     DefWndProc(msg);          // Windows handles other messages
  219. }
  220.  
  221. // Reset all alarms if system time is changed
  222. void TPardonDlg::WMTimeChange(RTMessage)
  223. {
  224.   SetAlarms();
  225. }
  226.  
  227. // Respond to WMTimer messages every 30 seconds or so
  228. void TPardonDlg::WMTimer(RTMessage)
  229. {
  230.   int testDay;
  231.   GetDayTime(testDay, theTime);  // Get current day and time
  232.   if (testDay != theDay) {       // If the day has changed
  233.     theDay = testDay;            //   save new day number
  234.     SetAlarms();                 //   reset all alarms
  235.   }
  236.   for (int i = 0; i < NUMALARMS; i++) {
  237.     if (theTime >= alarms[i].alarmTime && alarms[i].alarmSet) {
  238.       alarms[i].alarmSet = 0;      // Turn off the alarm
  239.       theMsg = alarms[i].alarmMsg; // Assign message address
  240.       SendDlgItemMsg(ID_TEXT, WM_SETTEXT, 0, long(theMsg));
  241.       Show(SW_SHOWNORMAL);         // Open possibly iconic window
  242.       BringWindowToTop(HWindow);   // Bring open window forward
  243.       MessageBeep(0);              // Get user's attention
  244.       return;                      // Exit function immediately
  245.     }
  246.   }
  247. }
  248.  
  249. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
  250.   LPSTR lpCmdLine, int nCmdShow)
  251. {
  252.   TPardonApp MiniApp(APP_NAME, hInstance, hPrevInstance,
  253.     lpCmdLine, nCmdShow);
  254.   MiniApp.Run();
  255.   return MiniApp.Status;
  256. }
  257.